#include "test_internal.hpp"

#include <intrin.h>

//#include <gvl/cstdint.hpp>
//#include <gvl/support/bits.hpp>

#include "lj_lib.h"

static luaL_Reg test[] =
{
	LUAN(test),
	{NULL, NULL}
};

int luaopen_test(lua_State* L)
{
	luaL_openlib(L, "test", test, 1);

	return 1;
}

struct stream_state
{
	stream_state()
	: out_bit_count(0)
	, out_buf(0)
	, n(0)
	{
	}

	int out_bit_count;
	uint32_t out_buf;

	int n;
	uint32_t buffer[64];
};

stream_state global_state;

LUAF(test)
{
	uint32_t i = (uint32_t)L->top[-2].n;
	int bits = (uint32_t)L->top[-1].n;

	stream_state& state = global_state;
	int bit_count = state.out_bit_count;
	uint32_t buf = state.out_buf | (i << bit_count);

	bit_count += bits;

	if(bit_count >= 32)
	{
		state.buffer[state.n] = buf;
		if(++state.n == 64)
			state.n = 0;

		bit_count -= 32;
		int consumed_bits = bits - bit_count;
		buf = (i << 1) << (consumed_bits - 1);
	}

	state.out_buf = buf;
	state.out_bit_count = bit_count;

	return 0;
}